package com.bupt.uchouten.common.block.entity;

import com.bupt.uchouten.common.linkage.TenkaiVVInnerPixelmonBlockEntity;
import com.bupt.uchouten.common.register.UchoutenBlockEntities;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.Connection;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectCategory;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraftforge.fml.ModList;

import java.util.List;
import java.util.Optional;

/**
 * @author wujichen158
 */
public class TenkaiVigorousVineBlockEntity extends BlockEntity {

    private TenkaiVVInnerPixelmonBlockEntity innerPixelmonBlockEntity;

    public TenkaiVigorousVineBlockEntity(BlockPos blockPos, BlockState state) {
        super(UchoutenBlockEntities.TENKAI_VIGOROUS_VINE_BLOCK_ENTITY.get(), blockPos, state);
        if (ModList.get().isLoaded("pixelmon")) {
            innerPixelmonBlockEntity = new TenkaiVVInnerPixelmonBlockEntity();
        }
    }

    public TenkaiVVInnerPixelmonBlockEntity getInnerPixelmonBlockEntity() {
        return this.innerPixelmonBlockEntity;
    }


    /**
     * 方块实体tick时执行的方法。每5秒给玩家应用一次效果
     *
     * @param level       所处维度
     * @param blockPos    方块位置
     * @param state       方块状态
     * @param blockEntity 方块实体对象
     */
    public static void tick(Level level, BlockPos blockPos, BlockState state, TenkaiVigorousVineBlockEntity blockEntity) {
        if (level.getGameTime() % 100L == 0L) {
            applyEffects(level, blockPos);
        }
        if (ModList.get().isLoaded("pixelmon")) {
            blockEntity.getInnerPixelmonBlockEntity().tick(level, blockPos, state, blockEntity);
        }
    }

    /**
     * 对玩家应用6秒的生命恢复1
     * 并清除玩家的负面效果
     *
     * @param level    所处维度
     * @param blockPos 方块位置
     */
    private static void applyEffects(Level level, BlockPos blockPos) {
        if (!level.isClientSide) {
            // 模仿信标的范围检测方式，检测方块周围边长为9的立方体
            AABB aabb = (new AABB(blockPos)).inflate(5);
            List<Player> list = level.getEntitiesOfClass(Player.class, aabb);

            for (Player player : list) {
                // 应用效果
                player.addEffect(new MobEffectInstance(MobEffects.REGENERATION, 120, 0, true, true));
                // 清除负面效果
                if (!player.level().isClientSide) {
                    for (MobEffectInstance mobEffectInstance : player.getActiveEffects()) {
                        MobEffect effect = mobEffectInstance.getEffect();
                        if (effect.getCategory() == MobEffectCategory.HARMFUL) {
                            player.removeEffect(effect);
                        }
                    }
                }
            }

        }
    }

    @Override
    public CompoundTag getUpdateTag() {
        CompoundTag nbt = new CompoundTag();

        if (ModList.get().isLoaded("pixelmon")) {
            this.saveAdditional(nbt);
            this.getInnerPixelmonBlockEntity().getUpdateTag(nbt);
        }

        return nbt;
    }

    @Override
    public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt) {
        if (ModList.get().isLoaded("pixelmon")) {
            Optional.ofNullable(pkt.getTag()).ifPresent(nbt -> {
                this.load(nbt);
                this.getInnerPixelmonBlockEntity().onDataPacket(nbt);
            });
        }
    }

    @Override
    public ClientboundBlockEntityDataPacket getUpdatePacket() {
        return ClientboundBlockEntityDataPacket.create(this);
    }

    public InteractionResult use(Player player) {
        if (ModList.get().isLoaded("pixelmon")) {
            return this.getInnerPixelmonBlockEntity().use(this, player);
        }
        return InteractionResult.SUCCESS;
    }
}
